iT邦幫忙

2026 iThome 鐵人賽

DAY 1
0
Software Development

Spring Boot + Kotlin 協程高併發,後端開發新選擇系列 第 1

Day 00:Spring Boot 3 + Kotlin 協程高併發,後端開發新選擇

  • 分享至 

  • xImage
  •  

如果你是一個習慣寫 Java 後端的工程師,大概對這個畫面不陌生。系統上線初期流量還小,每個 API 都反應飛快,Controller 收到請求,Service 呼叫下游,Repository 打資料庫,一條 Thread 從頭跟到尾,簡單直觀。直到某天流量開始往上衝,你打開監控面板,發現 Thread Pool 使用率貼著上限跑,新進來的請求開始排隊,有些甚至直接逾時。你加大 Thread Pool 設定,暫時緩解,過幾天流量再漲一階,同樣的警報又跳出來。你開始懷疑,問題是不是根本不在 Thread 數量夠不夠,而在於每一條 Thread 大半時間都在等,等資料庫回應、等外部 API 回應,卻仍然白白佔著一條作業系統等級的資源不放。

這時候你可能已經聽過 Kotlin 協程這個詞,甚至讀過幾篇介紹 suspend 關鍵字的文章,知道它能讓程式碼看起來像同步、實際上卻不阻塞執行緒。但知道這件事和真的把它用進一個 Spring Boot 後端服務,中間隔著一段不小的距離。協程官方文件會告訴你 launchasyncDispatchers 怎麼用,卻不會告訴你在一個每秒要扛住數千請求的訂單服務裡,什麼時候該用 Semaphore 節流、什麼時候該設 withTimeout、資料庫連線池又該怎麼配置才不會在協程情境下被悄悄耗盡。這中間的落差,正是這個系列要補上的部分。

這個系列要帶你做的事

這個系列不會把 30 天內容寫成 Kotlin 協程官方文件或 Spring 官方文件的中文導讀。核心立場很明確,目標不是背熟協程有哪些 API,而是遇到一個具體的高併發情境時,你知道該用哪個協程機制、為什麼是它而不是別的選項、如果不用又會付出什麼代價。終極目的是讓你能對照自己原本熟悉的 Thread 模型,講得出協程模型的差異與取捨,而不是換一套語法把同一套思維重寫一遍。

做法是全系列共用一個輕量示範情境,一個訂單查詢與扣庫存服務。這個情境從第一天只是一個單一的 suspend function 雛形開始出現,隨著系列推進,逐步加上限流、逾時、資料庫連線池這些真實情境會遇到的複雜度,到了系列後段的實戰整合期,收斂成一個具備監控、壓力測試、部署經驗的完整服務。這個情境刻意保持輕量,每天只取用其中一個切片,你不需要回頭補完整段程式碼才看得懂當天內容,但如果你一路跟到最後,會清楚感覺到這個服務隨著系列推進逐漸長大、逐漸貼近真正會上線的生產環境長相。

目標讀者,以及和另一個系列的分工

這個系列鎖定三種讀者輪廓,你可能同時符合不只一種。第一種是 Java 後端工程師,正打算或正在轉往 Kotlin,但還沒真正建立協程的心智模型,習慣 Thread、Executor 這類傳統並發思維,需要有人把協程「翻譯」成你已經熟悉的概念,再一步步拉開兩者的差異。第二種是對 Kotlin 語法已經有基礎,看得懂 data class、擴充函式、Lambda,但沒有 Spring Boot 後端實戰經驗,還需要補齊 Controller、Service、Repository 這些基本分層與請求生命週期的知識。第三種讀者可能連 Thread-per-Request 這種傳統模型實際怎麼運作都還不熟悉,這系列不會預設你已經懂,會在深入協程前先把這塊地基補上。

如果你曾經找過 Kotlin 協程的中文教學,可能會注意到我另外也寫過一個系列,「異步程式設計修煉:Kotlin Coroutines 完全指南」,同樣談協程,但那個系列聚焦在協程作為一套語言機制本身,不綁定任何後端框架,講的是協程在純 Kotlin 世界裡怎麼運作。這個系列不一樣,會把協程放進 Spring Boot 後端的高併發情境裡實戰,從 API 收到請求的那一刻開始,一路談到資料庫交易、連線池、壓力測試與上線部署。兩個系列不是誰取代誰,如果你連 suspend function 都還沒摸過,那個系列會是更基礎的起點;但你不需要先讀過那個系列才能開始這裡,這個系列本身也會從 suspend function 重新講起,只是講完基礎地基之後,很快就會把重心放回「這在 Spring Boot 後端裡到底該怎麼用」這個問題上。

30 天完整地圖

以下依五個階段分組呈現整個系列的全貌。每個階段標題下方先說明這個階段要讓你建立起什麼樣的能力,再列出該階段每一天的標題與一句話定位。閱讀當下不需要理解每一天的技術細節,只需要對整體節奏有個印象,等你實際走到某一天,回來這裡對照一下自己的位置即可。

階段一:地基期,從 Thread 模型到第一個協程,Day 01 - Day 04

四天,目標是建立協程存在的動機、對照傳統並發模型,寫出並看懂第一個 suspend function

  • 《Day 01:為什麼高併發後端需要協程,從一個會卡住的 API 說起》,建立協程存在的動機,定案示範情境:訂單查詢與扣庫存服務
  • 《Day 02:Thread-per-Request 模型的極限,搞懂你原本在用什麼》,定案 Thread-per-Request 模型錨點,講清楚傳統並發的成本來源
  • 《Day 03:第一個 suspend function,協程到底暫停了什麼》,定案 suspend function 錨點,建立協程「暫停不等於阻塞」的心智模型
  • 《Day 04:小結:把 Thread 模型與協程模型放在一起比一次》,整合前三天內容,用同一個情境對照兩種模型的行為差異,緩衝日

階段二:協程核心觀念期,結構化並發與執行環境,Day 05 - Day 09

五天,目標是建立 Coroutine Scope、Structured Concurrency、Dispatchers、Context、例外處理這些協程核心機制的正確心智模型。

  • 《Day 05:Coroutine Scope,協程住在哪裡、活多久》,定案 Coroutine Scope 錨點,建立協程生命週期容器的概念
  • 《Day 06:Structured Concurrency,為什麼協程不能亂長亂放》,定案 Structured Concurrency 錨點,解釋父子協程的收斂規則
  • 《Day 07:Dispatchers,協程實際跑在哪條執行緒上》,定案 Dispatchers 錨點,區分 Default、IO、Main 的適用情境
  • 《Day 08:Coroutine Context 與例外處理,協程出錯了誰負責》,定案 Coroutine Context 錨點,補齊協程例外傳播與處理機制
  • 《Day 09:小結:四個核心觀念如何在一次請求中協同運作》,整合 Scope、Structured Concurrency、Dispatchers、Context,緩衝日

階段三:生態整合期,協程與 Spring Boot 生態系搭配,Day 10 - Day 14

五天,目標是理解協程如何分別與 Spring MVC、WebFlux、R2DBC、訊息佇列等既有機制搭配,掌握選型判斷依據。

  • 《Day 10:在 Spring MVC 裡寫 suspend function,能動但有代價》,定案協程與 Spring MVC 整合模式錨點,講清楚底層仍是阻塞式容器的限制
  • 《Day 11:WebFlux 是什麼,協程與反應式模型的分工》,定案 WebFlux 反應式模型錨點,釐清協程與 Reactor 的關係而非誰取代誰
  • 《Day 12:R2DBC,讓資料庫存取也不阻塞執行緒》,定案 R2DBC 錨點,技術棧定案為 PostgreSQL + R2DBC,補齊非阻塞資料庫存取的基本操作與限制
  • 《Day 13:協程搭配訊息佇列與外部 API 呼叫的常見模式》,用示範情境的扣庫存流程示範協程如何包裝外部呼叫
  • 《Day 14:小結:三種技術選型的判斷依據,MVC、WebFlux 各用在哪》,收斂選型判斷依據,承先啟後預告即將進入高併發控制,關鍵轉折日

階段四:併發深化期,高併發控制與效能調校,Day 15 - Day 21

七天,目標是掌握併發限制、逾時取消、背壓、連線池搭配、效能量測比較這些生產環境必備的控制手段。

  • 《Day 15:併發限制,用 Semaphore 保護下游別被打爆》,定案併發限制錨點,示範同時扣庫存請求過多時的呼叫端節流手段,與資料列層級併發正確性問題區分開來
  • 《Day 16:逾時與取消,讓卡住的協程別拖垮整個系統》,定案逾時與取消機制錨點,示範 withTimeout 與取消傳播
  • 《Day 17:背壓是什麼,生產太快時該怎麼踩煞車》,定案背壓錨點,用 Channel 或 Flow 示範速度不對等的因應策略
  • 《Day 18:協程遇上 R2DBC 連線池,小心連線被偷偷耗盡》,定案 R2DBC 連線池搭配注意事項錨點,示範非阻塞連線池在協程高併發下的風險情境
  • 《Day 19:幫協程模型量身打造一場效能比較》,定案效能比較基準錨點,統一採用 k6 設計 Thread-per-Request 與協程的量測情境
  • 《Day 20:實測結果解讀,協程贏在哪裡、代價又是什麼》,承接 Day 19 的 k6 量測設計,解讀結果並誠實列出協程模型的取捨
  • 《Day 21:小結:高併發控制的工具箱總覽,準備進實戰》,回顧本階段所有控制手段,預告實戰整合期,緩衝日

階段五:實戰整合期,專案、可觀測性與部署,Day 22 - Day 30

九天,目標是把前四階段觀念收斂進一個具名示範專案,補齊監控、日誌、壓力測試、部署上線的完整經驗。本階段自 Day 22 起不建立可下載的完整原始碼倉庫,各天僅以程式碼片段搭配說明呈現。

  • 《Day 22:收斂進一個具名專案,訂單服務實戰整合版啟動》,定案示範專案錨點,把前四階段觀念收斂進具名專案的骨架,以程式碼片段呈現,不建立可下載倉庫
  • 《Day 23:把併發控制手段實際裝進訂單服務》,延續 Day 22,實際加上限流、逾時、取消機制的程式碼片段
  • 《Day 24:庫存扣減的併發正確性,用資料庫機制取代分散式鎖》,定案庫存扣減併發控制錨點,示範樂觀鎖或 SELECT FOR UPDATE 搭配 R2DBC 交易與協程的做法
  • 《Day 25:可觀測性第一步,讓協程執行狀況不再是黑盒子》,導入日誌與追蹤機制,處理協程情境下 Log 難以對應請求的常見痛點
  • 《Day 26:Metrics 與監控,量化你的協程效能表現》,導入 Micrometer 等監控手段,把 Day 19-20 的 k6 量測經驗落地成持續監控
  • 《Day 27:壓力測試,驗證系統在高併發下真的撐得住》,延用 Day 19-20 的 k6 方法論,設計並執行壓測情境,驗證前面所有控制手段是否真的有效
  • 《Day 28:部署上線的協程專屬檢查清單》,收斂部署前容易被忽略的協程相關設定,如執行緒池大小、逾時參數、R2DBC 連線池大小
  • 《Day 29:全系列整合驗收,跑一次完整的高併發情境》,端到端驗證示範專案在真實高併發情境下的完整行為
  • 《Day 30:完賽總結,Kotlin 協程適合與不適合的情境》,呼應 Day 1 的動機,誠實檢討協程模型的限制,系列收尾

小結:這套地圖存在的意義

30 天的天數配置刻意不均分,這是一套有意識設計的難度曲線。前兩個階段合計用掉 9 天把地基與核心觀念打穩,目的是避免你在還沒理解 Structured Concurrency 之前,就被丟進 Semaphore、Channel 這些進階控制手段,只能似懂非懂地照抄用法。併發深化期拉到七天,是因為這正是「高併發」這個系列標題真正要兌現的部分,也是多數協程教學文章停在語法介紹就打住、沒有真正碰觸的區域。實戰整合期收在九天,讓你看到前面所有觀念最終如何收斂進一個具備監控、壓測、部署經驗的完整服務,而不是學完一堆零散技巧後就沒有下文。

這份地圖上的每一格,都是為了回應開場那個會卡住的 API。它不會因為你讀完 30 天就自動消失,但你會清楚知道,下次面對類似情境時,問題出在哪一層,該用哪個協程機制回應,以及選擇協程之後,你實際上是在用什麼代價換取什麼好處。這件事光看地圖還無法被說服,需要跟著往下走,一步一步驗證。

明天我們將正式進入《Day 01:為什麼高併發後端需要協程,從一個會卡住的 API 說起》,把今天先按下不表的那個會卡住的 API,攤開來看清楚它到底卡在哪裡。


下一篇
Day 01:為什麼高併發後端需要協程,從一個會卡住的 API 說起
系列文
Spring Boot + Kotlin 協程高併發,後端開發新選擇4
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言